package youdu

import (
	"crypto/tls"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"strings"
	"youdu/model"
)

// YouduApiRequest 通用的有度API请求函数
func (o *tools) ApiRequest(
	apiServer string,
	buin int,
	appId string,
	encodedAesKey string,
	apiPath string,
	data interface{}) ([]byte, error) {

	// 解码AES密钥
	aesKey, err := Tools.DecodeAESKey(encodedAesKey)
	if err != nil {
		return nil, err
	}

	// 获取访问令牌
	accessToken, err := Tools.GetAccessToken(apiServer, buin, appId, encodedAesKey)
	if err != nil {
		return nil, fmt.Errorf("获取access_token失败: %v", err)
	}

	// 如果 apiPath 包含 ? 就用 & 连接
	var span string = "?"
	if strings.Contains(apiPath, "?") {
		span = "&"
	}
	// 忽略ssl
	tr := &http.Transport{
		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
	}
	client := &http.Client{
		Transport: tr,
	}
	// 构造请求地址
	url := fmt.Sprintf("%s%s%saccessToken=%s", apiServer, apiPath, span, accessToken)
	var resp *http.Response
	var respErr error
	var postBody string
	// 如果 data 是 nil 就用 GET 请求
	if data == nil {
		resp, respErr = client.Get(url)
		postBody = fmt.Sprintf("GET %s", url)
	} else {
		// 将消息转换为JSON
		msgJSON, err := json.Marshal(data)
		if err != nil {
			return nil, fmt.Errorf("消息序列化失败: %v", err)
		}

		// 加密消息内容
		encrypt, err := Tools.AesEncrypt(msgJSON, aesKey, appId)
		if err != nil {
			return nil, fmt.Errorf("加密消息内容失败: %v", err)
		}

		// 构造请求体
		reqBody := model.UniApiRequest{
			Buin:    buin,
			AppId:   appId,
			Encrypt: encrypt,
		}

		reqData, err := json.Marshal(reqBody)
		if err != nil {
			return nil, fmt.Errorf("请求数据序列化失败: %v", err)
		}
		resp, respErr = client.Post(
			url,
			"application/json",
			strings.NewReader(string(reqData)),
		)

		//
		postBody = fmt.Sprintf("%s | %s", string(reqData), string(msgJSON))
	}
	if respErr != nil {
		return nil, fmt.Errorf("发送API请求失败: %v", respErr)
	}
	defer resp.Body.Close()

	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("有度已返回：读取响应body失败: %v", err)
	}

	var result model.UniApiResponse
	if err := json.Unmarshal(body, &result); err != nil {
		return nil, fmt.Errorf("有度已返回：解析响应数据失败: %v | %s | %s", err, string(body), postBody)
	}

	if result.ErrCode != 0 {
		return nil, fmt.Errorf("有度已返回：API请求失败: %s | %s", result.ErrMsg, postBody)
	}
	// 判断是否有返回的密文字段
	if result.Encrypt != "" {
		// 解密返回的密文
		decrypt, err := Tools.AesDecrypt(result.Encrypt, aesKey, appId)
		if err != nil {
			return nil, fmt.Errorf("有度已返回：解密返回的密文失败: %v", err)
		}
		// 返回解密后的数据
		return decrypt.Data, nil

	}
	// 如果没有密文，直接返回响应数据
	return nil, nil
}
